<template>
  <div class="base-setting p-4">
    <BasicForm @register="registerForm" />
  </div>
</template>
<script lang="ts" setup name="BaseSetting">
  import { markRaw, ref, computed, watch, nextTick } from 'vue';
  import { BasicForm, useForm } from '/@/components/Form/index';
  import { Base, Connection, Label, Shape } from 'diagram-js/lib/model';
  import EventEmitter from '/@/utils/bpmn/EventEmitter';
  import { debounce } from 'lodash-es';
  import Logger from '/@/utils/bpmn/Logger';
  import { basicSchemas } from '../side.data';
  import modelerStore from '/@/store/modules/bpmnModeler';
  import {
    getNameValue,
    setNameValue,
  } from '/@/components/BpmnChart/src/components/Panel/bo-utils/nameUtil';

  const props = defineProps({
    tabType: Number,
  });
  const emit = defineEmits(['changeType']);
  const modeler = modelerStore();
  const isRemove = ref<boolean>(false);
  const [registerForm, { setFieldsValue, updateSchema }] = useForm({
    layout: 'vertical',
    schemas: basicSchemas,
    showActionButtonGroup: false,
  });
  const activities = computed(() => modeler.getActivities);

  // 设置元素属性
  const setCurrentElement = debounce((element: Shape | Base | Connection | Label | null) => {
    let activatedElement: BpmnElement | null | undefined = element;
    if (!activatedElement) {
      ifShowDetail(false);
      activatedElement =
        modeler.getElRegistry?.find((el) => el.type === 'bpmn:Process') ||
        modeler.getElRegistry?.find((el) => el.type === 'bpmn:Collaboration');
      setFieldsValue({
        activityName: activatedElement?.businessObject.name,
        bpmnId: activatedElement?.id,
      });
      if (!activatedElement) {
        return Logger.prettyError('No Element found!');
      }
    }

    EventEmitter.emit('element-update', activatedElement);
  }, 100);
  EventEmitter.on('modeler-init', (bpmnModeler) => {
    // 导入完成后默认选中 process 节点
    bpmnModeler.on('import.done', () => {
      setCurrentElement(null);
    });
    // 监听选择事件，修改当前激活的元素以及表单
    // modeler.on('selection.changed', ({ newSelection }) => {
    //   setCurrentElement(newSelection[0] || null);
    // });
    bpmnModeler.on(
      'element.changed',
      debounce(async ({ element }) => {
        if (isRemove.value) {
          await setCurrentElement(null);
          isRemove.value = false;
        } else {
          await setCurrentElement(element);
          await setElementInfo(element);
        }
      }, 100),
    );

    bpmnModeler.on(
      'element.click',
      debounce(async ({ element }) => {
        await setCurrentElement(element);

        await setElementInfo(element);
      }, 100),
    );

    bpmnModeler.on('shape.remove', ({ element }) => {
      isRemove.value = true;
      if (
        element.type === 'bpmn:StartEvent' ||
        element.type === 'bpmn:UserTask' ||
        element.type === 'bpmn:ExclusiveGateway' ||
        element.type === 'bpmn:Task' ||
        element.type === 'bpmn:EndEvent'
      ) {
        deleteElement(element.id);
      }
    });
    bpmnModeler.on('connection.remove', () => {
      isRemove.value = true;
      // modeler.deleteElement(element.id);
    });
    bpmnModeler.on('commandStack.shape.create.postExecuted', (event) => {
      addElement(event.context.shape);
    });
    bpmnModeler.on('commandStack.connection.create.postExecuted', (event) => {
      setNameValue(event.context.connection, { id: `sf_${++flowInfo.value.flowLineMaxId}` });
    });
  });
  // 新增元素
  const flowInfo = computed(() => modeler.getFlowInfo);
  function addElement(element) {
    modeler.setElement(markRaw(element), setBpmnId(element.type));

    if (!setBpmnId(element.type) || setBpmnId(element.type) === 'none') {
      return;
    }
    if (flowInfo.value.activityMaxId) {
      flowInfo.value.activityMaxId++;
    } else {
      flowInfo.value.activityMaxId = 1;
    }
    const param = {
      bpmnId: setBpmnId(element.type),
      activityType: setBpmnType(element.type),
      activityName: '',
      activityId: flowInfo.value.activityMaxId,
      condition: null,
    };
    // if (setBpmnType(element.type) === 1 || setBpmnType(element.type) === 2) {
    //   param.condition = condition;
    // } else if (setBpmnType(element.type) === 9) {
    //   param.condition = conditionEnd;
    // }
    setNameValue(element, { name: '', id: setBpmnId(element.type) });
    modeler.addElement(param);
    emit('changeType', 1);
  }
  // 设置事件类型
  function setBpmnType(val) {
    const imgMap = new Map([
      ['bpmn:StartEvent', -1],
      ['bpmn:UserTask', 1],
      ['bpmn:ExclusiveGateway', 5],
      ['bpmn:Task', 1],
      ['bpmn:EndEvent', 9],
    ]);
    return imgMap.get(val) || 0;
  }
  // 设置bpmnTd
  function setBpmnId(val) {
    let id = flowInfo.value.activityMaxId;
    let isHaveStart = activities.value.some((i) => i.activityType === -1);
    if (val === 'bpmn:StartEvent' && !isHaveStart) {
      id = 0;
    }
    const imgMap = new Map([
      ['bpmn:StartEvent', `start_${id}`],
      ['bpmn:UserTask', `userTask_${id}`],
      ['bpmn:ExclusiveGateway', `userTask_${id}`],
      ['bpmn:Task', `userTask_${id}`],
      ['bpmn:EndEvent', `end_${id}`],
    ]);
    return imgMap.get(val) || 'none';
  }

  // 点击流程获取节点属性
  function setElementInfo(activatedElement) {
    let id;
    if (activatedElement?.type === 'label') {
      id = activatedElement?.businessObject.id;
    } else {
      id = activatedElement?.id;
    }
    modeler.setElement(markRaw(activatedElement), id);
    const name = getNameValue(activatedElement);
    modeler.setActivitiesItem(id, 'activityName', name);
    const item = activities.value?.find((i) => i.bpmnId === id);

    //处理用户数据格式
    if (item) {
      setFieldsValue(item);
      modeler.setNodeItem(item);
      // 当步骤类型为以下值时需要被隐藏的组件
      const ifShowArr = [-1, 5, 9];

      nextTick(() => {});
      if (ifShowArr.includes(item.activityType)) {
        ifShowDetail(false);
      } else {
        ifShowDetail(true);
      }
    } else {
      modeler.setNodeItem(null);

      setFieldsValue({
        activityName: activatedElement.businessObject.name,
        bpmnId: id,
      });
      ifShowDetail(false);
    }
  }

  function deleteElement(id) {
    const index = activities.value.findIndex((item) => item.bpmnId === id);
    activities.value.splice(index, 1);
    modeler.setNodeItem(null);
  }
  const configuration = computed(() => modeler.getConfiguration);
  function ifShowDetail(flag) {
    nextTick(() => {
      updateSchema([
        {
          field: 'rangeType',
          ifShow: flag,
        },
        {
          field: 'participantRange',
          ifShow: flag,
        },
        {
          field: 'selectUserNum',
          ifShow: flag,
        },

        // {
        //   field: 'rangeComponentType',
        //   ifShow: flag,
        // },
        {
          field: 'maxLimitedNum',
          ifShow: flag,
        },
        {
          field: 'baseInfo.responseChoices',
          ifShow: flag,
        },

        {
          field: 'rights',
          ifShow: flag,
        },
        {
          field: 'allowRecallFlag',
          ifShow: flag,
        },
        {
          field: 'verifySignatureFlag',
          ifShow: flag,
        },
        {
          field: 'notifyInitiatorFlag',
          ifShow: flag,
        },
        {
          field: 'activityType',
          ifShow: flag,
        },
        {
          field: 'fieldPerms',
          ifShow: flag,
        },
        {
          field: 'transRoles',
          ifShow: flag,
        },
      ]);
    });
  }
  watch(
    () => props.tabType,
    (val) => {
      if (val === 3) {
        const rights = configuration.value.rights.map((i) => ({
          label: i.rightName,
          value: i.rightId,
        }));
        nextTick(() => {
          updateSchema({
            field: 'rights',
            componentProps: {
              options: rights,
            },
          });
        });
      }
    },
    { deep: true },
  );
  // watch(
  //   () => modeler.nodeItem?.activityType,
  //   () => {
  //     nextTick(() => {
  //       // const startFlag = activities.value.some((i) => i.activityType === 0);
  //       // updateSchema({
  //       //   field: 'activityType',
  //       //   componentProps: {
  //       //     options: [
  //       //       {
  //       //         label: '开始类型',
  //       //         value: 0,
  //       //         disabled: startFlag,
  //       //       },
  //       //       {
  //       //         label: '任务类型',
  //       //         value: 1,
  //       //       },
  //       //       {
  //       //         label: '通知类型',
  //       //         value: 2,
  //       //       },
  //       //     ],
  //       //   },
  //       // });
  //     });
  //   },
  // );
</script>
<style lang="less" scoped>
  .base-setting {
    overflow-y: auto;
    height: calc(100% - 78px);
  }
</style>
